package com.system.aop;


import java.lang.reflect.Method;
import java.util.Date;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import com.system.annotation.SystemServiceLog;
import com.system.log.entity.Log;
import com.system.log.service.LogService;

@Aspect
@SuppressWarnings("rawtypes")
public class SystemLogAspect {

@Autowired
private LogService logService;

    /**
     * 日志记录
     */
    //private static final Logger LOGGER = Logger.getLogger(SystemLogAspect.class);

     /**
      * Service层切点
      */
     @Pointcut("@annotation(com.system.annotation.SystemServiceLog)")    
     public void serviceAspect() {
         
     }
     
     /**
     * doServiceLog:获取注解参数，记录日志. <br/>
     * @author lcma
     * @param joinPoint 切入点参数
     * @since JDK 1.7
     */
    @After("serviceAspect()") 
     public  void doServiceLog(JoinPoint joinPoint) {
    //LOGGER.info("日志记录");
    		Subject subject = SecurityUtils.getSubject();
    		Session session = subject.getSession();  
    		String userName = (String) session.getAttribute("userName");
         	System.out.println(userName);
          try {
             //数据库日志
        	 String methodName = joinPoint.getSignature().getName(); 
             Log log = new Log();
             log.setOperationType(getServiceMthodTableType(joinPoint));
             //获取日志描述信息
             String content = getServiceMthodDescription(joinPoint);
             log.setContent(userName + content);
             log.setRemarks(adminOptionContent(joinPoint.getArgs(), methodName));
             log.setCreatedate(new Date());
             logService.saveOrUpdate(log);
         }  catch (Exception e) {  
             //LOGGER.error("异常信息:{}", e);
         }    
     }
    /**
     * getServiceMthodDescription:获取注解中对方法的描述信息 用于service层注解  . <br/>
     * @author lcma
     * @param joinPoint 切点 
     * @return 方法描述
     * @throws Exception 
     * @since JDK 1.7
     */
    private String getServiceMthodDescription(JoinPoint joinPoint)
               throws Exception {
          String targetName = joinPoint.getTarget().getClass().getName();
          String methodName = joinPoint.getSignature().getName();
          Object[] arguments = joinPoint.getArgs();
          Class targetClass = Class.forName(targetName);
          Method[] methods = targetClass.getMethods();
          String description = "";
           for(Method method : methods) {
               if(method.getName().equals(methodName)) {
                  Class[] clazzs = method.getParameterTypes();
                   if(clazzs.length == arguments.length) {
                      description = method.getAnnotation(SystemServiceLog.class).description();
                       break;
                  }
              }
          }
          return description;
      }
    
    /**
     * getServiceMthodTableType:获取注解中对方法的数据表类型 用于service层注解 . <br/>
     * @author lcma
     * @param joinPoint
     * @return
     * @throws Exception
     * @since JDK 1.7
     */
    private int getServiceMthodTableType(JoinPoint joinPoint)
            throws Exception {
       String targetName = joinPoint.getTarget().getClass().getName();
       String methodName = joinPoint.getSignature().getName();
       Object[] arguments = joinPoint.getArgs();
       Class targetClass = Class.forName(targetName);
       Method[] methods = targetClass.getMethods();
       int tableType = 0;
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
               Class[] clazzs = method.getParameterTypes();
                if (clazzs.length == arguments.length) {
                tableType = method.getAnnotation(SystemServiceLog.class).tableType();
                    break;
               }
           }
       }
        return tableType;
   }
    
    /**
     * getServiceMthodParams:获取json格式的参数. <br/>
     * @author lcma
     * @param joinPoint
     * @return
     * @throws Exception
     * @since JDK 1.7
     */
//    private String getServiceMthodParams(JoinPoint joinPoint)
//            throws Exception {
//       Object[] arguments = joinPoint.getArgs();
//       String params = JacksonUtil.toJSon(arguments);
//       return arguments;
//   }
    public String adminOptionContent(Object[] args, String mName) throws Exception{  
    	  
        if (args == null) {  
            return null;  
        }  
          
        StringBuffer rs = new StringBuffer();  
        rs.append(mName);  
        String className = null;  
        int index = 1;  
        // 遍历参数对象  
        for (Object info : args) {  
              
            //获取对象类型  
            className = info.getClass().getName();  
            className = className.substring(className.lastIndexOf(".") + 1);  
            rs.append("[参数" + index + "，类型：" + className + "，值：");  
              
            // 获取对象的所有方法  
            Method[] methods = info.getClass().getDeclaredMethods();  
              
            // 遍历方法，判断get方法  
            for (Method method : methods) {  
                  
                String methodName = method.getName();  
                // 判断是不是get方法  
                if (methodName.indexOf("get") == -1) {// 不是get方法  
                    continue;// 不处理  
                }  
                  
                Object rsValue = null;  
                try {  
                      
                    // 调用get方法，获取返回值  
                    rsValue = method.invoke(info);  
                      
                    if (rsValue == null) {//没有返回值  
                        continue;  
                    }  
                      
                } catch (Exception e) {  
                    continue;  
                }  
                  
                //将值加入内容中  
                rs.append("(" + methodName + " : " + rsValue + ")");  
            }  
              
            rs.append("]");  
              
            index++;  
        }  
          
        return rs.toString();  
    }  

}
